#pragma once 
#include "Util.hpp"
#include "Log.hpp"
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

#define SEP ": "


class HttpRequest{
  public:
    std::unordered_map<std::string, std::string> _header_kv;

    std::string _request_line;
    std::vector<std::string> _request_header;
    std::string _blank;
    std::string _request_body;

    //解析完毕的结果
    std::string _mthod;  //请求方法
    std::string _uri;    //请求资源
    std::string _version;//请求版本
};


class HttpResponse{
  private:
  public:
    std::string _response_line;
    std::vector<std::string> _response_header;
    std::string _blank;
    std::string _response_body;
};



//读取请求，分析请求，构建相应
//IO通信
class EndPoint{
  private:
    void RecvHttpRequestLine();
    void RecvHttpRequestHeader();
    void ParseHttpRequestLine();
    void ParseHttpRequestHeader();
  public:
    EndPoint(int sock) :_sock(sock){}
    void RecvHttpRequest();
    void ParseHttpRequest();
    void BuildHttpResponse(){};
    void SendHttpResponse(){};
    ~EndPoint() {close(_sock);}
  private:
    int _sock;
    HttpRequest  _http_request;
    HttpResponse _http_response;
};

void EndPoint::RecvHttpRequestLine(){
  size_t size = Util::ReadLine(_sock, _http_request._request_line);
  _http_request._request_line.resize(size - 1);
  //test
  //copy.resize(copy.size() - 1);
  //LOG(INFO, copy);
}

void EndPoint::RecvHttpRequestHeader(){
  std::string line;
  std::string copy;
  while (line != "\n"){
    line.clear();
    copy.clear();
    Util::ReadLine(_sock, line);
    copy = line;
    copy.resize(copy.size() - 1);
    _http_request._request_header.push_back(copy);
    //test
    //std::string copy = line;
    //copy.resize(copy.size() - 1);
    //LOG(INFO, copy);
  }
  if (line == "\n"){
    _http_request._blank = line;
  }
}

void EndPoint::RecvHttpRequest(){
    RecvHttpRequestLine();
    RecvHttpRequestHeader();
}

void EndPoint::ParseHttpRequest(){
  ParseHttpRequestLine();
  ParseHttpRequestHeader();
}

void EndPoint::ParseHttpRequestLine(){ 
  auto& line = _http_request._request_line;
  std::stringstream ss(line);
  ss >> _http_request._mthod >> _http_request._uri >> _http_request._version;
  //LOG(INFO, _http_request._mthod);
  //LOG(INFO, _http_request._uri);
  //LOG(INFO, _http_request._version);
}

void EndPoint::ParseHttpRequestHeader(){
  for (auto &iter : _http_request._request_header){
    std::string key; 
    std::string value;
    if (Util::CutString(iter, key, value, SEP)){
      std::cout << "debug :" << key << std::endl;
      std::cout << "debug :" << value << std::endl;
    }
    else{
      std::string ret = key + value + "Cutstring errno";
      LOG(ERRNO, ret);
    }
  }
}



class Entrance{
  public:
    static void* HandlerRequest(void* args){
      LOG(INFO, "handler request begin");
      int sock = *(int*)args;
      delete (int*)args;
      //std::cout << "get a new link" << sock << std::endl;

#ifdef DEBUG 
      char buffer[1024 * 10] = {0};
      std::cout << "\n\n----------------------"<<std::endl;
      recv(sock, buffer, sizeof(buffer) - 1, 0);
      std::cout << buffer << std::endl;
      std::cout << "\n\n----------------------"<<std::endl;
#else 
      EndPoint *ep = new EndPoint(sock);
      ep->RecvHttpRequest();
      ep->ParseHttpRequest();
      ep->BuildHttpResponse();
      ep->SendHttpResponse();
      delete ep;
#endif
      //std::string line;
      //Util::ReadLine(sock, line);
      //std::cout << line << std::endl;
      close(sock);
      LOG(INFO, "handler request end");
      return nullptr;
    }
};



